<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch } from 'vue'
import { init as initEChart, type ECharts, type EChartsOption, type SeriesOption } from 'echarts'
import {
  LengthInput,
  SpeedType,
  SpeedUnit,
  SpeedUnitSelect,
  fromMpsConvert,
  notify,
  speedUnitName,
  SpeedTypeSelect,
  m2ft
} from '@/widgets'
import BADAAircraftTypeSelect from './BADAAircraftTypeSelect.vue'
import { calcRocSpdProfileById, type ROCSpdItem, type ROCSpdProfile } from './roc-spd'

const acType = ref<string>('A320')
const alt = ref<number>(3000)
const esf = ref<number>(0.86)
const pwc = ref(0.95)

function getESF(): number {
  if (typeof esf.value === 'string') {
    return parseFloat(esf.value)
  }
  return esf.value
}

function getPWC(): number {
  if (typeof pwc.value === 'string') {
    return parseFloat(pwc.value)
  }
  return pwc.value
}
const rocUnit = ref(SpeedUnit.FTPM)
const spdType = ref(SpeedType.CAS)
const spdUnit = ref(SpeedUnit.KT)

let profile: ROCSpdProfile
function updateData() {
  profile = calcRocSpdProfileById(acType.value, {
    ESF: getESF(),
    alt: alt.value,
    PWC: getPWC()
  })
}

const chartEl = ref<HTMLDivElement>()
let chart: ECharts

function updateChart(): void {
  if (!chart) {
    return
  }
  chart.clear()
  const opts: EChartsOption = {
    tooltip: {
      axisPointer: { type: 'cross' }
    },
    legend: {},
    title: {
      text: `${acType.value}爬升率-速度`,
      subtext: makeSubTitle()
    },
    backgroundColor: '#fff',
    xAxis: {
      name: getSpdName(),
      type: 'value',
      min: 'dataMin'
    },
    yAxis: [
      {
        name: `ROC(${speedUnitName(rocUnit.value)})`,
        type: 'value',
        min: 'dataMin'
      },
      {
        name: '阻力(N)',
        type: 'value',
        min: 'dataMin'
      }
    ],
    series: makeSeries()
  }
  chart.setOption(opts)
}

function getSpdName(): string {
  if (spdType.value === SpeedType.Mach) {
    return 'Ma'
  }
  return `${spdType.value}(${speedUnitName(spdUnit.value)})`
}

function makeSubTitle(): string {
  let ret = '大气模型:\nISA\n'
  ret += `ESF:\n${profile.ESF}\n`
  ret += `PWC:\n${profile.PWC}\n`
  ret += `质量:\n${profile.mass}t\n`
  ret += `推力:\n${Math.floor(profile.thrust)}n\n`
  ret += `高度:\n${Math.floor(profile.alt)}m\n`
  ret += `${Math.floor(m2ft(profile.alt))}ft`
  return ret
}

function makeSeries(): SeriesOption[] {
  const { line } = profile
  const xFn = getSpdFn()
  const yFn = getROCFn()
  return [
    {
      type: 'line',
      name: '爬升率',
      showSymbol: false,
      data: line.map((e) => [xFn(e), yFn(e)]),
      yAxisIndex: 0
    },
    {
      type: 'line',
      name: '阻力',
      showSymbol: false,
      data: line.map((e) => [xFn(e), Math.floor(e.drag)]),
      yAxisIndex: 1
    }
  ]
}
function getROCFn(): (e: ROCSpdItem) => number {
  const fn = fromMpsConvert(rocUnit.value)
  if (rocUnit.value === SpeedUnit.FTPM) {
    return (e) => Math.floor(fn(e.ROC))
  }
  return (e) => Math.round(fn(e.ROC) * 100.0) / 100.0
}

function getSpdFn(): (e: ROCSpdItem) => number {
  if (spdType.value === SpeedType.Mach) {
    return (e) => Math.round(e.mach * 100.0) / 100.0
  }
  const spdFn = fromMpsConvert(spdUnit.value)
  const spdFn1 = (e: number) => Math.floor(spdFn(e))
  if (spdType.value === SpeedType.CAS) {
    return (e) => spdFn1(e.CAS)
  }
  return (e) => spdFn1(e.TAS)
}

onMounted(() => {
  chart = initEChart(chartEl.value)
  updateData()
  updateChart()
})

onUnmounted(() => {
  chart?.dispose()
})

watch(spdType, updateChart)
watch(spdUnit, updateChart)
watch(rocUnit, updateChart)

function calc() {
  if (isNaN(alt.value)) {
    notify.error({ content: '高度错误！' })
    return
  }
  if (isNaN(getESF())) {
    notify.error({ content: '能量分配系数错误' })
    return
  }
  if (isNaN(getPWC())) {
    notify.error({ content: '减推力系数错误' })
    return
  }
  updateData()
  updateChart()
}
</script>
<template>
  <div class="bada-roc-spd pane-block">
    <div class="row">
      <div class="txt-box col-3em">机型</div>
      <BADAAircraftTypeSelect class="col-6em" v-model="acType" />
      <div class="txt-box col-3em" style="margin-left: 2em">高度</div>
      <LengthInput v-model="alt" class="col-8em" />
      <div class="txt-box col-11em" style="margin-left: 2em">能量分配系数(ESF|f{M})</div>
      <input class="input col-4em" type="number" v-model="esf" />
      <div class="txt-box col-9em" style="margin-left: 2em">减推力系数(PWC)</div>
      <input class="input col-4em" type="number" v-model="pwc" />
      <button class="button is-primary" style="margin-left: 4em" @click="calc">计算</button>
    </div>
    <div class="row">
      <div class="txt-box col-3em">速度</div>
      <SpeedTypeSelect class="col-6em" v-model="spdType" />
      <div class="txt-box col-5em" style="margin-left: 2em">速度单位</div>
      <SpeedUnitSelect
        class="col-6em"
        v-model="spdUnit"
        :options="[SpeedUnit.MPS, SpeedUnit.KMPH, SpeedUnit.KT]"
      />
      <div class="txt-box col-6em" style="margin-left: 2em">爬升率单位</div>
      <SpeedUnitSelect v-model="rocUnit" :options="[SpeedUnit.MPS, SpeedUnit.FTPM]" />
    </div>
    <hr class="border-bottom" style="margin: 0.5em 0" />
    <div class="rs-chart" ref="chartEl"></div>
  </div>
</template>
<style lang="scss">
.bada-roc-spd {
  .rs-chart {
    width: 70em;
    height: 40em;
  }
}
</style>
